//
//  LcNotificationCenter.m
//  18Birdies
//
//  Created by Lc on 15/4/13.
//  Copyright (c) 2015年 Lc. All rights reserved.
//

#import "LcLog.h"
#import "LcNotificationCenter.h"
#import "LcPreconditions.h"
#import "LcWeakReference.h"

@interface LcNotificationCenter ()
@property(nonatomic, strong) NSMutableArray* weakDelegates;
@property(nonatomic, assign) int memoryLeakCount;
@end

@implementation LcNotificationCenter

- (void)internalInit {
  self.weakDelegates = [NSMutableArray array];
}

- (void)registerDelegate:(id<LcNotificationDelegate>)delegate {
  LC_CHECK_NOT_NULL(delegate);
  if (![self ckeckExists:delegate remove:NO]) {
    LcWeakReference* weakDelegate =
        [LcWeakReference weakReferenceWithObject:delegate];
    [self.weakDelegates addObject:weakDelegate];
  }
  LcLog(@"LcNotificationCenter.delegates.count=%lu",
        (unsigned long)self.weakDelegates.count);
}

- (void)unregisterDelegate:(id<LcNotificationDelegate>)delegate {
  LC_CHECK_NOT_NULL(delegate);
  [self ckeckExists:delegate remove:YES];
  LcLog(@"LcNotificationCenter.delegates.count=%lu",
        (unsigned long)self.weakDelegates.count);
}

- (void)sendNotification:(NSString*)notification {
  LC_CHECK_NOT_EMPTY(notification);
  [self sendNotification:notification auxiliary:nil];
}

- (void)sendNotification:(NSString*)notification auxiliary:(id)auxiliary {
  LC_CHECK_NOT_EMPTY(notification);
  NSMutableArray* nilDelegates = [NSMutableArray array];
  NSArray* weakCopyDelegates = [self.weakDelegates copy];
  for (NSInteger i = weakCopyDelegates.count - 1; i >= 0; --i) {
    LcWeakReference* weakDelegate = weakCopyDelegates[i];
    id<LcNotificationDelegate> delegate = weakDelegate.object;
    if (delegate == nil) {
      [nilDelegates addObject:weakCopyDelegates[i]];
    } else {
      if ([NSThread isMainThread]) {
        [delegate notificationReceived:notification auxiliary:auxiliary];
      } else {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
          [delegate notificationReceived:notification auxiliary:auxiliary];
        }];
      }
    }
  }
  [self.weakDelegates removeObjectsInArray:nilDelegates];
}

- (BOOL)ckeckExists:(id<LcNotificationDelegate>)delegate remove:(BOOL)remove {
  LC_CHECK_NOT_NULL(delegate);
  BOOL found = NO;
  for (NSInteger i = self.weakDelegates.count - 1; i >= 0; --i) {
    LcWeakReference* weakDelegate = self.weakDelegates[i];
    id<LcNotificationDelegate> existDelegate = weakDelegate.object;
    if (existDelegate == nil) {
      [self.weakDelegates removeObjectAtIndex:i];
    } else if (delegate == existDelegate) {
      found = YES;
      if (remove) {
        [self.weakDelegates removeObjectAtIndex:i];
      }
    }
  }
  return found;
}

- (NSArray*)allDelegates {
  return self.weakDelegates.copy;
}

@end
